#ifndef __M_CONN_H__
#define __M_CONN_H__

#include"mq_channel.hpp"

namespace xiang11mq
{
    
class Connection
{
public: 
    using ptr = std::shared_ptr<Connection>;
    Connection(const VirtualHost::ptr &host,
            const ConsumerManager::ptr &cmp,
            const ProtobufCodecPtr &codec,
            const muduo::net::TcpConnectionPtr &conn,
            const threadPool::ptr &pool)
            :_conn(conn)
            ,_codec(codec)
            ,_cmp(cmp)
            ,_host(host)
            ,_pool(pool)
            ,_channels(std::make_shared<ChannelManager>())
    {

    }
    //创建信道
    void openChannel(const openChannelRequestPtr &req)
    {
        //1.判断信道ID是否重复 创建信道
        bool ret = _channels->openChannel(req->cid(), _host, _cmp, _codec, _conn, _pool);
        if(ret == false)
        {
            DLOG("创建信道时 信道ID重复了 %s", req->cid().c_str());
            return basicResponse(false, req->rid(), req->cid());
        }
        //3.给客户端恢复
        DLOG("创建信道成功 %s", req->cid().c_str());
        return basicResponse(true, req->rid(), req->cid());
    }
    //删除信道
    void closeChannel(const closeChannelRequestPtr &req)
    {
        _channels->closeChannel(req->cid());
        return basicResponse(true, req->rid(), req->cid());
    }
    Channel::ptr getChannel(const std::string &cid)
    {
        return _channels->getChannel(cid);
    }
private:
    void basicResponse(bool ok, const std::string &rid, const std::string &cid)
    {
        basicCommonResponse resp;
        resp.set_rid(rid);
        resp.set_cid(cid);
        resp.set_ok(ok);
        _codec->send(_conn, resp);
    }
private:

    muduo::net::TcpConnectionPtr _conn; // 信道关联的连接：⽤于向客⼾端发送数据
    ProtobufCodecPtr _codec;            // protobuf协议处理句柄：⽹络通信前的协议处理
    ConsumerManager::ptr _cmp;          // 消费者管理句柄
    VirtualHost::ptr _host;             // 虚拟机管理句柄
    threadPool::ptr _pool;
    ChannelManager::ptr _channels;      //信道管理句柄
};

//连接管理类
class ConnectionManager
{
public:
    using ptr = std::shared_ptr<ConnectionManager>;
    ConnectionManager()
    {}
    void newConnection(const VirtualHost::ptr &host,
            const ConsumerManager::ptr &cmp,
            const ProtobufCodecPtr &codec,
            const muduo::net::TcpConnectionPtr &conn,
            const threadPool::ptr &pool)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _conns.find(conn);
        if(it != _conns.end())
        {
            DLOG("要创建的链接已存在");
            return;
        }
        auto self_conn = std::make_shared<Connection>(host, cmp, codec, conn, pool);
        _conns.insert(std::make_pair(conn, self_conn));

    }
    void delConnection(const muduo::net::TcpConnectionPtr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _conns.erase(conn);
    }
    Connection::ptr getConnection(const muduo::net::TcpConnectionPtr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _conns.find(conn);
        if(it == _conns.end())
        {
            DLOG("要查找的链接不存在");
            return Connection::ptr();
        }
        return it->second;
    }

private:
    std::mutex _mutex;
    std::unordered_map<muduo::net::TcpConnectionPtr, Connection::ptr> _conns;
};

} 


#endif

